// Copyright 2006 Two Pair, LLC. All Rights Reserved.
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

/**
 * Runs a command-line application for counting the number of occurrences of all
 * words or phrases in a file.
 */
public class Histo {

  /**
   * Run a command-line application to count the number of occurrences of all
   * words or phrases in a file.
   * 
   * @param args the command-line arguments
   */
  public static void main(String[] args) {
    String fileName = null;
    try {
      // Process arguments
      UserSettings settings = ArgumentProcessor.process(args);
      fileName = settings.getFileName();
      InputStream in;
      if (fileName != null) {
        in = FileStreamCreator.createInputStream(fileName);
      } else {
        in = System.in;
      }

      // Process the input
      WordLexer wordLexer = new WordLexer(settings.getCharacterAnalyzer());
      PhraseCounter phraseCounter = new PhraseCounter(
          settings.getWordAnalyzer(), settings.getPhraseLength());
      wordLexer.processInput(in, phraseCounter);

      // Print the output
      Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
      phraseCounter.printResults(out, settings.getThreshold());

      // normal status code 0 exit
      return;
    } catch (IllegalArgumentException e) {
      System.err.println("Error: " + e.getMessage());
    } catch (FileNotFoundException e) {
      System.err.println("Error: input file '" + fileName + "' does not exist");
    } catch (IOException e) {
      System.err.println("Error: input file '" + fileName
          + "' cannot be read from");
    } catch (OutOfMemoryError e) {
      System.err.println("Error: out of memory; the file may be too large");
    } catch (Throwable e) {
      System.err.println("Error: program terminated unexpectedly");
    }
    // error exit
    System.exit(-1);
  }

  /**
   * Not instantiable.
   */
  private Histo() {
  }

}
